This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

source("./tianfengRwrappers.R")
CA_dataset2 <- readRDS("./CA_dataset2.rds")
# CA_dataset2 <- RenameIdents(CA_dataset2,'EC' = 'Endothelial cell','FB' = 'Fibroblast')

umap图

小提琴图

vio <- violin_plot(c("MS4A1","PECAM1","FBLN1","CD68","TPSAB1","STMN1","NKG7","TAGLN","IL7R"), CA_dataset2) + 
  theme(axis.text.y = element_text(size = 18,colour = "black")) + scale_x_discrete(position = "right")
Scale for 'x' is already present. Adding another scale for 'x', which will replace the existing scale.

热图 top30的marker,展示其中的部分

```r
Idents(CA_dataset2) <- CA_dataset2$Classification1
CA_dataset2_markers <- FindAllMarkers(CA_dataset2, logfc.threshold = 1, min.diff.pct = 0.3)
top30genes <- CA_dataset2_markers[CA_dataset2_markers$pct.1>0.7,] %>% group_by(cluster) %>% slice_max(n = 30, order_by = avg_logFC)

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->



<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxubGlicmFyeShDb21wbGV4SGVhdG1hcClcbiMj5o+Q5Y+W5qCH5YeG5YyW6KGo6L6+55+p6Zi1XG5tYXQgPC0gR2V0QXNzYXlEYXRhKENBX2RhdGFzZXQyLCBzbG90ID0gXFxzY2FsZS5kYXRhXFwpXG5cbmdlbmVfc2hvdyA8LSBjKFxcTFlaXFwsXFxDRDY4XFwsXFxTUFAxXFwsXFxQRUNBTTFcXCxcXFZXRlxcLFxcUExWQVBcXCxcXE1ZTDlcXCxcXFRBR0xOXFwsXFxBQ1RBMlxcLFxcRENOXFwsXFxBUE9EXFwsXFxGQkxOMVxcLFxcQ0Q2OVxcLFxcQ0Q3OUFcXCxcXE1TNEExXFwsXFxUUFNBQjFcXCxcXFRQU0IyXFwsXFxOS0c3XFwsXFxTVE1OMVxcLFxcQ0VOUEZcXCxcXENQQTNcXCxcXElMN1JcXCxcXFRSQUNcXClcblxuIyPojrflvpfln7rlm6Dlkoznu4bog57ogZrnsbvkv6Hmga9cbmNsdXN0ZXJfaW5mbyA8LSBzb3J0KENBX2RhdGFzZXQyJENsYXNzaWZpY2F0aW9uMSlcbmNvbmRpdGlvbl9pbmZvIDwtIHNvcnQoQ0FfZGF0YXNldDIkY29uZGl0aW9ucylcbmhlYXRtYXBnZW5lcyA8LSBpbnRlcnNlY3QodG9wMzBnZW5lcyRnZW5lLHJvd25hbWVzKG1hdCkpXG5cbiMj562b6YCJ55+p6Zi1XG5tYXQgPC0gYXMubWF0cml4KG1hdFtoZWF0bWFwZ2VuZXMsbmFtZXMoY2x1c3Rlcl9pbmZvKV0pXG5cbiPojrflvpfln7rlm6DlnKjng63lm77kuK3nmoTkvY3nva7kv6Hmga9cbmdlbmVfcG9zIDwtIG1hdGNoKGdlbmVfc2hvdywgcm93bmFtZXMobWF0KSlcbnJvd19hbm5vIDwtIHJvd0Fubm90YXRpb24oZ2VuZT1hbm5vX21hcmsoYXQ9Z2VuZV9wb3MsbGFiZWxzID0gZ2VuZV9zaG93KSlcblxuY29sIDwtIGNvbG9yc19saXN0XG5uYW1lcyhjb2wpIDwtIGxldmVscyhjbHVzdGVyX2luZm8pXG50b3BfYW5ubyA8LSBIZWF0bWFwQW5ub3RhdGlvbihjbHVzdGVyPWFubm9fYmxvY2soZ3A9Z3BhcihmaWxsPWNvbCksbGFiZWxzID0gbGV2ZWxzKGNsdXN0ZXJfaW5mbyksXG4gbGFiZWxzX2dwID0gZ3BhcihjZXg9MSxjb2w9J2JsYWNrJykpKVxuXG5saWJyYXJ5KGNpcmNsaXplKVxuY29sX2Z1biA8LSAgY29sb3JSYW1wMihjKC0yLCAxLCA0KSwgYyhcXCMxRTkwRkZcXCwgXFx3aGl0ZVxcLCBcXCNmZjIxMjFcXCkpXG5cbnN2ZyhcXENBX2RhdGFzZXQyX21hcmtlcnMuc3ZnXFwsaGVpZ2h0ID0gNix3aWR0aCA9IDEwKVxuSGVhdG1hcChtYXQsIGNsdXN0ZXJfcm93cyA9IEZBTFNFLCBjbHVzdGVyX2NvbHVtbnMgPSBGQUxTRSwgXG4gICAgICAgIHNob3dfY29sdW1uX25hbWVzID0gRkFMU0UsIHNob3dfcm93X25hbWVzID0gRkFMU0UsXG4gY29sdW1uX3NwbGl0ID0gY2x1c3Rlcl9pbmZvLCB0b3BfYW5ub3RhdGlvbiA9IHRvcF9hbm5vLCAgXG4gY29sdW1uX3RpdGxlID0gTlVMTCwgcmlnaHRfYW5ub3RhdGlvbiA9IHJvd19hbm5vLCBcbiBoZWF0bWFwX2xlZ2VuZF9wYXJhbSA9IGxpc3QoXG4gdGl0bGU9J0V4cHJlc3Npb24nLCB0aXRsZV9wb3NpdGlvbj0nbGVmdGNlbnRlci1yb3QnKSwgY29sID0gY29sX2Z1bilcbmRldi5vZmYoKVxuYGBgXG5gYGAifQ== -->

```r
```r
library(ComplexHeatmap)
##提取标准化表达矩阵
mat <- GetAssayData(CA_dataset2, slot = \scale.data\)

gene_show <- c(\LYZ\,\CD68\,\SPP1\,\PECAM1\,\VWF\,\PLVAP\,\MYL9\,\TAGLN\,\ACTA2\,\DCN\,\APOD\,\FBLN1\,\CD69\,\CD79A\,\MS4A1\,\TPSAB1\,\TPSB2\,\NKG7\,\STMN1\,\CENPF\,\CPA3\,\IL7R\,\TRAC\)

##获得基因和细胞聚类信息
cluster_info <- sort(CA_dataset2$Classification1)
condition_info <- sort(CA_dataset2$conditions)
heatmapgenes <- intersect(top30genes$gene,rownames(mat))

##筛选矩阵
mat <- as.matrix(mat[heatmapgenes,names(cluster_info)])

#获得基因在热图中的位置信息
gene_pos <- match(gene_show, rownames(mat))
row_anno <- rowAnnotation(gene=anno_mark(at=gene_pos,labels = gene_show))

col <- colors_list
names(col) <- levels(cluster_info)
top_anno <- HeatmapAnnotation(cluster=anno_block(gp=gpar(fill=col),labels = levels(cluster_info),
 labels_gp = gpar(cex=1,col='black')))

library(circlize)
col_fun <-  colorRamp2(c(-2, 1, 4), c(\#1E90FF\, \white\, \#ff2121\))

svg(\CA_dataset2_markers.svg\,height = 6,width = 10)
Heatmap(mat, cluster_rows = FALSE, cluster_columns = FALSE, 
        show_column_names = FALSE, show_row_names = FALSE,
 column_split = cluster_info, top_annotation = top_anno,  
 column_title = NULL, right_annotation = row_anno, 
 heatmap_legend_param = list(
 title='Expression', title_position='leftcenter-rot'), col = col_fun)
dev.off()

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->


# 比例

<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuZ2dzYXZlKFwiQ0FkYXRhc2V0Ml9wcm9wLnN2Z1wiLGRldmljZSA9IHN2ZywgcGxvdCA9IHByb3BfcGxvdCx3aWR0aCA9IDYsaGVpZ2h0ID0gNSlcblxuYGBgIn0= -->

```r
ggsave("CAdataset2_prop.svg",device = svg, plot = prop_plot,width = 6,height = 5)
错误: Aesthetics must be either length 1 or the same as the data (18): fill
Run `rlang::last_error()` to see where the error occurred.

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gCgpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ3RybCtTaGlmdCtFbnRlciouIAoKYGBge3J9CnNvdXJjZSgiLi90aWFuZmVuZ1J3cmFwcGVycy5SIikKQ0FfZGF0YXNldDIgPC0gcmVhZFJEUygiLi9DQV9kYXRhc2V0Mi5yZHMiKQojIENBX2RhdGFzZXQyIDwtIFJlbmFtZUlkZW50cyhDQV9kYXRhc2V0MiwnRUMnID0gJ0VuZG90aGVsaWFsIGNlbGwnLCdGQicgPSAnRmlicm9ibGFzdCcpCmBgYAoKIyB1bWFw5Zu+CmBgYHtyIGZpZy53aWR0aCA9IDYsIGZpZy5oZWlnaHQgPSA1fQpnZ3NhdmUoIkNBX2RhdGFzZXQydW1hcC5zdmciLHBsb3QgPSB1bWFwcGxvdChDQV9kYXRhc2V0MiksZGV2aWNlID0gc3ZnLCB3aWR0aCA9IDYsIGhlaWdodCA9IDUpCgojIGZpZy4xCklkZW50cyhDQV9kYXRhc2V0MikgPC0gQ0FfZGF0YXNldDIkY29uZGl0aW9ucwp1bWFwX0FDIDwtIHVtYXBwbG90KHN1YnNldChDQV9kYXRhc2V0MiwgaWRlbnRzID0gIkFDIiksIGdyb3VwLmJ5ID0gIkNsYXNzaWZpY2F0aW9uMSIpCnVtYXBfUEEgPC0gdW1hcHBsb3Qoc3Vic2V0KENBX2RhdGFzZXQyLCBpZGVudHMgPSAiUEEiKSwgZ3JvdXAuYnkgPSAiQ2xhc3NpZmljYXRpb24xIikKZ2dzYXZlKCJ1bWFwX0FDLnN2ZyIscGxvdCA9IHVtYXBfQUMsZGV2aWNlID0gc3ZnLCB3aWR0aCA9IDcsIGhlaWdodCA9IDUpCmdnc2F2ZSgidW1hcF9QQS5zdmciLHBsb3QgPSB1bWFwX1BBLGRldmljZSA9IHN2Zywgd2lkdGggPSA3LCBoZWlnaHQgPSA1KQoKIyMgZmlnLjIgCmdnc2F2ZSgiZHMyX1BBdW1hcC5zdmciLHBsb3QgPSB1bWFwcGxvdChkczJfUEEpLGRldmljZSA9IHN2Zywgd2lkdGggPSA2LCBoZWlnaHQgPSA1KQpnZ3NhdmUoImRzMl9BQ3VtYXAuc3ZnIixwbG90ID0gdW1hcHBsb3QoZHMyX0FDKSxkZXZpY2UgPSBzdmcsIHdpZHRoID0gNiwgaGVpZ2h0ID0gNSkKYGBgCgojIOWwj+aPkOeQtOWbvgpgYGB7cn0KSWRlbnRzKENBX2RhdGFzZXQyKSA8LSBDQV9kYXRhc2V0MiRDbGFzc2lmaWNhdGlvbjEKdmlvIDwtIHZpb2xpbl9wbG90KGMoIk1TNEExIiwiUEVDQU0xIiwiRkJMTjEiLCJDRDY4IiwiVFBTQUIxIiwiU1RNTjEiLCJOS0c3IiwiVEFHTE4iLCJJTDdSIiksIENBX2RhdGFzZXQyKSArIAogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCxjb2xvdXIgPSAiYmxhY2siKSkKZ2dzYXZlKCJDQWRhdGFzZXQyX21hcmtlcnNfdmlvLnN2ZyIsZGV2aWNlID0gc3ZnLCBwbG90ID0gdmlvLHdpZHRoID0gNiwgaGVpZ2h0ID0gNikKYGBgCgoKIyDng63lm74gdG9wMzDnmoRtYXJrZXLvvIzlsZXnpLrlhbbkuK3nmoTpg6jliIYKYGBge3J9CklkZW50cyhDQV9kYXRhc2V0MikgPC0gQ0FfZGF0YXNldDIkQ2xhc3NpZmljYXRpb24xCkNBX2RhdGFzZXQyX21hcmtlcnMgPC0gRmluZEFsbE1hcmtlcnMoQ0FfZGF0YXNldDIsIGxvZ2ZjLnRocmVzaG9sZCA9IDEsIG1pbi5kaWZmLnBjdCA9IDAuMykKdG9wMzBnZW5lcyA8LSBDQV9kYXRhc2V0Ml9tYXJrZXJzW0NBX2RhdGFzZXQyX21hcmtlcnMkcGN0LjE+MC43LF0gJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSBzbGljZV9tYXgobiA9IDMwLCBvcmRlcl9ieSA9IGF2Z19sb2dGQykKYGBgCgpgYGB7cixmaWcud2lkdGg9NixmaWcuaGVpZ2h0PTR9CmxpYnJhcnkoQ29tcGxleEhlYXRtYXApCiMj5o+Q5Y+W5qCH5YeG5YyW6KGo6L6+55+p6Zi1Cm1hdCA8LSBHZXRBc3NheURhdGEoQ0FfZGF0YXNldDIsIHNsb3QgPSAic2NhbGUuZGF0YSIpCgpnZW5lX3Nob3cgPC0gYygiTFlaIiwiQ0Q2OCIsIlNQUDEiLCJQRUNBTTEiLCJWV0YiLCJQTFZBUCIsIk1ZTDkiLCJUQUdMTiIsIkFDVEEyIiwiRENOIiwiQVBPRCIsIkZCTE4xIiwiQ0Q2OSIsIkNENzlBIiwiTVM0QTEiLCJUUFNBQjEiLCJUUFNCMiIsIk5LRzciLCJTVE1OMSIsIkNFTlBGIiwiQ1BBMyIsIklMN1IiLCJUUkFDIikKCiMj6I635b6X5Z+65Zug5ZKM57uG6IOe6IGa57G75L+h5oGvCmNsdXN0ZXJfaW5mbyA8LSBzb3J0KENBX2RhdGFzZXQyJENsYXNzaWZpY2F0aW9uMSkKY29uZGl0aW9uX2luZm8gPC0gc29ydChDQV9kYXRhc2V0MiRjb25kaXRpb25zKQpoZWF0bWFwZ2VuZXMgPC0gaW50ZXJzZWN0KHRvcDMwZ2VuZXMkZ2VuZSxyb3duYW1lcyhtYXQpKQoKIyPnrZvpgInnn6npmLUKbWF0IDwtIGFzLm1hdHJpeChtYXRbaGVhdG1hcGdlbmVzLG5hbWVzKGNsdXN0ZXJfaW5mbyldKQoKI+iOt+W+l+WfuuWboOWcqOeDreWbvuS4reeahOS9jee9ruS/oeaBrwpnZW5lX3BvcyA8LSBtYXRjaChnZW5lX3Nob3csIHJvd25hbWVzKG1hdCkpCnJvd19hbm5vIDwtIHJvd0Fubm90YXRpb24oZ2VuZT1hbm5vX21hcmsoYXQ9Z2VuZV9wb3MsbGFiZWxzID0gZ2VuZV9zaG93KSkKCmNvbCA8LSBjb2xvcnNfbGlzdApuYW1lcyhjb2wpIDwtIGxldmVscyhjbHVzdGVyX2luZm8pCnRvcF9hbm5vIDwtIEhlYXRtYXBBbm5vdGF0aW9uKGNsdXN0ZXI9YW5ub19ibG9jayhncD1ncGFyKGZpbGw9Y29sKSxsYWJlbHMgPSBsZXZlbHMoY2x1c3Rlcl9pbmZvKSwKIGxhYmVsc19ncCA9IGdwYXIoY2V4PTEsY29sPSdibGFjaycpKSkKCmxpYnJhcnkoY2lyY2xpemUpCmNvbF9mdW4gPC0gIGNvbG9yUmFtcDIoYygtMiwgMSwgNCksIGMoIiMxRTkwRkYiLCAid2hpdGUiLCAiI2ZmMjEyMSIpKQoKc3ZnKCJDQV9kYXRhc2V0Ml9tYXJrZXJzLnN2ZyIsaGVpZ2h0ID0gNix3aWR0aCA9IDEwKQpIZWF0bWFwKG1hdCwgY2x1c3Rlcl9yb3dzID0gRkFMU0UsIGNsdXN0ZXJfY29sdW1ucyA9IEZBTFNFLCAKICAgICAgICBzaG93X2NvbHVtbl9uYW1lcyA9IEZBTFNFLCBzaG93X3Jvd19uYW1lcyA9IEZBTFNFLAogY29sdW1uX3NwbGl0ID0gY2x1c3Rlcl9pbmZvLCB0b3BfYW5ub3RhdGlvbiA9IHRvcF9hbm5vLCAgCiBjb2x1bW5fdGl0bGUgPSBOVUxMLCByaWdodF9hbm5vdGF0aW9uID0gcm93X2Fubm8sIAogaGVhdG1hcF9sZWdlbmRfcGFyYW0gPSBsaXN0KAogdGl0bGU9J0V4cHJlc3Npb24nLCB0aXRsZV9wb3NpdGlvbj0nbGVmdGNlbnRlci1yb3QnKSwgY29sID0gY29sX2Z1bikKZGV2Lm9mZigpCmBgYAoKIyDmr5TkvosKYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9IDZ9CklkZW50cyhDQV9kYXRhc2V0MikgPC0gQ0FfZGF0YXNldDIkY29uZGl0aW9ucwpwcm9wX21hdCA8LSBjYmluZChwcm9wLnRhYmxlKHRhYmxlKHN1YnNldChDQV9kYXRhc2V0MiwgaWRlbnRzID0gIkFDIikkQ2xhc3NpZmljYXRpb24xKSkscHJvcC50YWJsZSh0YWJsZShzdWJzZXQoQ0FfZGF0YXNldDIsIGlkZW50cyA9ICJQQSIpJENsYXNzaWZpY2F0aW9uMSkpKQpjb2xuYW1lcyhwcm9wX21hdCkgPC0gYygiQUMiLCJQQSIpCgpwbG90X2RhdGEgPSBtZWx0KHByb3BfbWF0KQpjb2xuYW1lcyhwbG90X2RhdGEpID0gYygnY2VsbCB0eXBlJywncG9zaXRpb24nLCdwcm9wb3J0aW9uJykj5L+u5pS55q+P5LiA5YiX55qE5ZCN56ewCiMgCiMgZ2dwbG90KHBsb3RfZGF0YSwgYWVzKHggPSBgY2VsbCB0eXBlYCwgeSA9IHByb3BvcnRpb24sIGZpbGwgPSBwb3NpdGlvbikpICsgCiMgICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JywgcG9zaXRpb24gPSAiZG9kZ2UiLCB3aWR0aD0wLjUpICsgdGhlbWVfYncoKQoKcHJvcF9wbG90IDwtIGdncGxvdChwbG90X2RhdGEsIGFlcyh4ID0gYGNlbGwgdHlwZWAsIHkgPSBwcm9wb3J0aW9uLCBmaWxsID0gcG9zaXRpb24pKSArIAogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknLCBwb3NpdGlvbiA9ICJzdGFjayIsIHdpZHRoID0gMC41KSArIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLDAuNSkpKwogIHRoZW1lX2J3KCkgKyBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLDApKSArICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiI2IxZDZmYiIsICIjZmQ5OTk5IikpKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksIGF4aXMudGV4dC54ID0gCiAgICAgIGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxLCBhbmdsZSA9IDQ1LCBjb2xvdXIgPSAiYmxhY2siKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLCBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLAogICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpKQoKZ2dzYXZlKCJDQWRhdGFzZXQyX3Byb3Auc3ZnIixkZXZpY2UgPSBzdmcsIHBsb3QgPSBwcm9wX3Bsb3Qsd2lkdGggPSA2LGhlaWdodCA9IDUpCgpgYGAKCkFkZCBhIG5ldyBjaHVuayBieSBjbGlja2luZyB0aGUgKkluc2VydCBDaHVuayogYnV0dG9uIG9uIHRoZSB0b29sYmFyIG9yIGJ5IHByZXNzaW5nICpDdHJsK0FsdCtJKi4KCldoZW4geW91IHNhdmUgdGhlIG5vdGVib29rLCBhbiBIVE1MIGZpbGUgY29udGFpbmluZyB0aGUgY29kZSBhbmQgb3V0cHV0IHdpbGwgYmUgc2F2ZWQgYWxvbmdzaWRlIGl0IChjbGljayB0aGUgKlByZXZpZXcqIGJ1dHRvbiBvciBwcmVzcyAqQ3RybCtTaGlmdCtLKiB0byBwcmV2aWV3IHRoZSBIVE1MIGZpbGUpLgoKVGhlIHByZXZpZXcgc2hvd3MgeW91IGEgcmVuZGVyZWQgSFRNTCBjb3B5IG9mIHRoZSBjb250ZW50cyBvZiB0aGUgZWRpdG9yLiBDb25zZXF1ZW50bHksIHVubGlrZSAqS25pdCosICpQcmV2aWV3KiBkb2VzIG5vdCBydW4gYW55IFIgY29kZSBjaHVua3MuIEluc3RlYWQsIHRoZSBvdXRwdXQgb2YgdGhlIGNodW5rIHdoZW4gaXQgd2FzIGxhc3QgcnVuIGluIHRoZSBlZGl0b3IgaXMgZGlzcGxheWVkLgo=